﻿package gases.as3.librarys.core.managers
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.utils.Dictionary;
	
	import gases.as3.librarys.core.Interface.IDispose;
	
	/**
	 * 事件管理类
	 * @author 
	 */
	public class GEventManager implements IDispose, IEventDispatcher
	{
		private var _listeners:Dictionary;
		private var _dispatcher:IEventDispatcher;
		
		/**
		 * 构造函数
		 * @param	d
		 */
		public function GEventManager(d:IEventDispatcher = null )
		{
			_listeners = new Dictionary(true);
			_dispatcher = (d ? d:new EventDispatcher());
		}
		
		/**
		 * 使用 EventDispatcher 对象注册事件侦听器对象，以使侦听器能够接收事件通知。
		 * @param	type
		 * @param	listener
		 * @param	useCapture
		 * @param	priority
		 * @param	useWeakReference
		 */
		public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
		{
			if (!getPair(type, listener, useCapture))
			{
				var obj:TypeListenerPair = new TypeListenerPair(type, listener, useCapture);
				_listeners[obj] = obj;
				_dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
			}
		}
		
		/**
		 * 从 EventDispatcher 对象中删除侦听器。
		 * @param	type
		 * @param	listener
		 * @param	useCapture
		 */
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
		{
			var pair:TypeListenerPair = getPair(type, listener, useCapture);
			if (pair)
			{
				_listeners[pair] = null;
				delete _listeners[pair];
				_dispatcher.removeEventListener(type, listener, useCapture);
			}
		}
		
		/**
		 * 检查 EventDispatcher 对象是否为特定事件类型注册了任何侦听器。
		 * @param	event
		 * @return
		 */
		public function hasEventListener(type:String):Boolean
		{
			return _dispatcher.hasEventListener(type);
		}
		
		/**
		 * 将事件调度到事件流中。 
		 * @param	event
		 * @return
		 */
		public function dispatchEvent(event:Event):Boolean 
		{
			//当派发者含有这个事件的侦听器,或者事件是冒泡时间时,才发送
			if (_dispatcher.hasEventListener(event.type) || event.bubbles)
				return	_dispatcher.dispatchEvent(event);
			return true;
		}
		
		/**
		 * 检查是否用此 EventDispatcher 对象或其任何始祖为指定事件类型注册了事件侦听器。
		 * @param	type
		 * @return
		 */
		public function willTrigger(type:String):Boolean 
		{
			return _dispatcher.willTrigger(type);
		}
		
		private function getPair(type:String, listener:Function, useCapture:Boolean):TypeListenerPair
		{	
			for each (var p:TypeListenerPair in _listeners)
				if (p.eventType == type && p.listener == listener && p.useCapture == useCapture)
					return p;
			return null;
		}
		
		/**
		 * 销毁函数
		 */
		public function dispose():void
		{
			for each(var p:TypeListenerPair in _listeners)
			{
				removeEventListener(p.eventType, p.listener, p.useCapture);
			}
			_listeners = null;
			_dispatcher = null;
		}
		
	}
	
}

class TypeListenerPair
{
	public var eventType:String;
	public var listener:Function;
	public var useCapture:Boolean;

	public function TypeListenerPair(type:String, listener_:Function,useCapture_:Boolean)
	{
		eventType = type;
		listener = listener_;
		useCapture = useCapture_;
	}
}